package com.lekang.service.impl;

import java.math.BigDecimal;
import java.util.List;

import com.lekang.common.utils.DateUtils;
import com.lekang.domain.Balance;
import com.lekang.domain.OrderManagement;
import com.lekang.mapper.BalanceMapper;
import com.lekang.mapper.OrderManagementMapper;
import com.lekang.mapper.TaskArrangementMapper;
import com.lekang.service.IBillService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.lekang.mapper.RefundRecordMapper;
import com.lekang.domain.RefundRecord;
import com.lekang.service.IRefundRecordService;

/**
 * 退款记录Service业务层处理
 *
 * @author ruitong
 * @date 2025-10-14
 */
@Service
public class RefundRecordServiceImpl implements IRefundRecordService
{
    private static final Logger log = LoggerFactory.getLogger(RefundRecordServiceImpl.class);

    @Autowired
    private RefundRecordMapper refundRecordMapper;

    @Autowired
    private OrderManagementMapper orderManagementMapper;

    @Autowired
    private BalanceMapper balanceMapper;

    @Autowired
    private TaskArrangementMapper taskArrangementMapper;

    @Autowired
    private IBillService billService;

    /**
     * 查询退款记录
     *
     * @param id 退款记录主键
     * @return 退款记录
     */
    @Override
    public RefundRecord selectRefundRecordById(Long id)
    {
        return refundRecordMapper.selectRefundRecordById(id);
    }

    @Override
    public RefundRecord selectRefundRecordByOrderNO(String orderNo) {
        return refundRecordMapper.selectRefundRecordByOrderNO(orderNo);
    }

    /**
     * 查询退款记录列表
     *
     * @param refundRecord 退款记录
     * @return 退款记录
     */
    @Override
    public List<RefundRecord> selectRefundRecordList(RefundRecord refundRecord)
    {
        return refundRecordMapper.selectRefundRecordList(refundRecord);
    }

    /**
     * 新增退款记录（事务保证：退款成功后更新余额、订单状态、账单状态并删除任务）
     * 
     * 执行步骤：
     * 1. 查询订单信息
     * 2. 更新老人预交款余额（退款金额）
     * 3. 删除关联的护理任务
     * 4. 更新订单状态为已退款(4)，交易状态为退款成功(3)
     * 5. 同步更新关联的费用账单状态为已关闭(2)
     * 6. 插入退款记录
     *
     * @param refundRecord 退款记录
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertRefundRecord(RefundRecord refundRecord)
    {
        log.info("========== 开始处理退款 ==========");
        log.info("订单ID: {}", refundRecord.getOrderId());
        log.info("订单号: {}", refundRecord.getOrderNo());
        log.info("退款金额: {}", refundRecord.getRefundAmount());

        // 1. 根据订单编号查询订单表数据
        OrderManagement orderManagement = orderManagementMapper.selectOrderManagementById(refundRecord.getOrderId());
        if (orderManagement == null) {
            log.error("订单不存在，订单ID: {}", refundRecord.getOrderId());
            throw new RuntimeException("订单不存在");
        }
        log.info("查询到订单信息：订单号={}, 老人ID={}", orderManagement.getOrderNo(), orderManagement.getElderlyId());

        Long elderlyId = orderManagement.getElderlyId();

        // 2. 查询老人余额记录并更新预交款余额
        Balance balance = balanceMapper.selectBalanceByElderlyId(elderlyId);
        if (balance != null) {
            BigDecimal currentBalance = balance.getPrepaymentBalance();
            if (currentBalance == null) {
                currentBalance = BigDecimal.ZERO;
            }
            log.info("当前预交款余额：{}", currentBalance);

            BigDecimal refundAmount = refundRecord.getRefundAmount();
            if (refundAmount == null) {
                refundAmount = BigDecimal.ZERO;
            }

            BigDecimal newBalance = currentBalance.add(refundAmount);
            log.info("退款金额：{}，新余额：{}", refundAmount, newBalance);

            balance.setPrepaymentBalance(newBalance);

            // 更新余额表
            int balanceUpdateResult = balanceMapper.updateBalance(balance);
            log.info("余额更新结果：{}", balanceUpdateResult > 0 ? "成功" : "失败");
        } else {
            log.warn("未找到老人余额记录，老人ID: {}", elderlyId);
        }

        // 3. 删除任务安排表中的关联任务（护理计划外任务）
        String orderNo = refundRecord.getOrderNo();
        int deletedTaskCount = taskArrangementMapper.deleteTaskArrangementByRelatedOrderNo(orderNo);
        log.info("删除任务数量: {}", deletedTaskCount);

        if (deletedTaskCount > 0) {
            log.info("成功删除订单号 {} 关联的任务", orderNo);
        } else {
            log.info("订单号 {} 没有关联的任务，或任务已被删除", orderNo);
        }

        // 4. 更新订单状态为已退款(4)，交易状态为退款成功(3)
        orderManagement.setOrderStatus(4L);  // 已退款
        orderManagement.setTransactionStatus(3L);  // 退款成功
        orderManagement.setUpdateTime(DateUtils.getNowDate());
        int orderUpdateResult = orderManagementMapper.updateOrderManagement(orderManagement);
        log.info("订单状态更新结果：{}", orderUpdateResult > 0 ? "成功" : "失败");
        
        if (orderUpdateResult <= 0) {
            log.error("更新订单状态失败，订单ID: {}", refundRecord.getOrderId());
            throw new RuntimeException("更新订单状态失败");
        }

        // 5. 同步更新关联的费用账单状态（已退款状态4对应账单已关闭状态"2"）
        boolean billUpdateResult = billService.updateBillStatusByOrderStatus(orderNo, 4L);
        log.info("账单状态同步结果：{}", billUpdateResult ? "成功" : "失败");

        // 6. 插入退款记录
        int result = refundRecordMapper.insertRefundRecord(refundRecord);
        log.info("退款记录插入结果：{}", result > 0 ? "成功" : "失败");
        log.info("========== 退款处理完成 ==========");

        return result;
    }

    /**
     * 修改退款记录
     *
     * @param refundRecord 退款记录
     * @return 结果
     */
    @Override
    public int updateRefundRecord(RefundRecord refundRecord)
    {
        return refundRecordMapper.updateRefundRecord(refundRecord);
    }

    /**
     * 批量删除退款记录
     *
     * @param ids 需要删除的退款记录主键
     * @return 结果
     */
    @Override
    public int deleteRefundRecordByIds(Long[] ids)
    {
        return refundRecordMapper.deleteRefundRecordByIds(ids);
    }

    /**
     * 删除退款记录信息
     *
     * @param id 退款记录主键
     * @return 结果
     */
    @Override
    public int deleteRefundRecordById(Long id)
    {
        return refundRecordMapper.deleteRefundRecordById(id);
    }
}